# -*- encoding: utf-8 -*-
#@author:侯松林

'''
4. 使用米粒图像，分割得到各米粒，首先计算各区域(米粒)的面积、长度等信息，进一步计算面积、长度的均值及方差，分析落在3sigma范围内米粒的数量。
'''
import numpy as np
import cv2
import copy

# 读取图像
img = cv2.imread(r'rice.png')
# cv2.imshow("img",img)

# 转化为灰度图像
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# cv2.imshow("img_gray",img_gray)


# 大津算法
# _,bw = cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

#使用局部阈值的大津算法进行图像二值化
bw = cv2.adaptiveThreshold(img_gray,255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,101, 1)
# cv2.imshow("OTSU",bw)

element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
bw = cv2.morphologyEx(bw,cv2.MORPH_OPEN,element)
cv2.imshow("OTSU2",bw)

seg = copy.deepcopy(bw)
bin,cnts,hier = cv2.findContours(seg,cv2.cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
count = 0
lenArray=[]
areaArray=[]
for i in range(len(cnts),0,-1):
    c = cnts[i-1]
    area = cv2.contourArea(c)
    if area<10:
        continue
    count = count +1
    x,y,w,h = cv2.boundingRect(c)
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,0xff),1)
    y = 10 if y < 10 else y  # 防止编号到图片之外
    cv2.putText(img,str(count),(x,y),cv2.FONT_HERSHEY_PLAIN,0.5,(0,0xff,0))
    length = round(np.sqrt(w*w+h*h),2)
    lenArray.append(length)
    areaArray.append(area)
    print("block",i,"area=" ,area,"length=",length)
print("米粒数量: ",count)
cv2.imshow("original", img)


len_arr_mean = np.mean(lenArray)
len_arr_var = np.var(lenArray)
len_arr_std = np.std(lenArray)
print("长度平均值为：%f" % len_arr_mean)
print("长度方差为：%f" % len_arr_var)
print("长度标准差为:%f" % len_arr_std)
# 3sigma范围的数据统计
i=0;
total=0;
for len in lenArray:
    total+=1
    if len_arr_mean-3*len_arr_std <= len < len_arr_mean+3*len_arr_std:
        i+=1
print("长度3sigma范围内数量：%d" % i)
print('长度3sigma范围内百分比: {:.2f}%'.format(i/total*100))

area_arr_mean = np.mean(areaArray)
area_arr_var = np.var(areaArray)
area_arr_std = np.std(areaArray)
print("面积平均值为：%f" % area_arr_mean)
print("面积方差为：%f" % area_arr_var)
print("面积标准差为:%f" % area_arr_std)
# 3sigma范围的数据统计
i=0;
total=0;
for area in areaArray:
    total+=1
    if area_arr_mean-3*area_arr_std <= area < area_arr_mean+3*area_arr_std:
        i+=1

print("面积3sigma范围内数量：%d" % i)
print('面积3sigma范围内百分比: {:.2f}%'.format(i/total*100))


'''
结论：
采用局部大津算法及开运算进行图像处理
米粒数量:  94
长度平均值为：29.343191
长度方差为：50.466592
长度标准差为:7.103984
长度3sigma范围内数量：93
长度3sigma范围内百分比: 98.94%
面积平均值为：172.648936
面积方差为：4224.477818
面积标准差为:64.995983
面积3sigma范围内数量：92
面积3sigma范围内百分比: 97.87%
分析：3sigma包含了绝大多数样本，近似高斯分布
'''

cv2.waitKey()
cv2.destroyAllWindows()